using System;
using System.Collections.Generic;
using System.Text;
using System.IO;
using System.Net;
using System.Xml;

namespace PocketLibrary.Management
{
    /// <summary>
    /// class for voo2do API
    /// </summary>
    public class voo2do : IService
    {
        #region IService Members

        ServiceType IService.ServiceType
        {
            get { return ServiceType.Management; }
        }

        #endregion

        #region constants
        private string voo2doURI = "http://voo2do.com/api/";

        #endregion

        #region events
        public event EventHandler OnLoggedIn;

        private void userloggedIn()
        {
            if (OnLoggedIn != null)
                OnLoggedIn(this, new EventArgs());
        }

        #endregion

        #region private variables
        private HttpWebRequest req;
        private HttpWebResponse resp;
        private XmlDocument xmlresponse = new XmlDocument();
        private string sRequestString = "";
        private string sRequestType = "";
        private Dictionary<string, string> dParams = new Dictionary<string, string>();


        private string sUsername = "";
        private string sPassword = "";
        private bool bLoggedIn = false;

        private string sLoginHash = "";
        private int iUserID = 0;


        // future features
        // feature to check voo2do at defined intervals
        //private bool bUseTimeCheck = false;
        //private long threadCheckTime = 0;

        private bool bRequesting = false;

        #endregion

        #region public variables
        public string Username
        {
            get
            {
                return sUsername;
            }
            set
            {
                sUsername = value;
            }
        }

        public string Password
        {
            get
            {
                return HelperUtils.MD5String(sPassword);
            }
            set
            {
                sPassword = value;
            }
        }

        public bool LoggedIn
        {
            get { return bLoggedIn; }
        }

        #endregion

        #region private methods
        private void executeRequest()
        {
            if (!bRequesting)
            {
                try
                {
                    prepareRequest();
                    req = (HttpWebRequest)WebRequest.Create(voo2doURI + sRequestString);
                    dParams.Clear();
                    req.Method = "GET";
                    req.UserAgent = "TaskuBlogi 1.0 voo2do client";
                    req.Timeout = 60000; // 60 seconds

                    resp = (HttpWebResponse)req.GetResponse();
                    Stream stResponse = resp.GetResponseStream();

                    xmlresponse.Load(stResponse);
                    stResponse.Close();
                    resp.Close();
                }
                catch (WebException e)
                {
                    System.Diagnostics.Debug.WriteLine("request failed " + sRequestString);
                    System.Diagnostics.Debug.WriteLine(e.Message);
                }
            }
        }

        private void prepareRequest()
        {
            StringBuilder sb = new StringBuilder();

            sb.Append(sRequestType);
            bool bFirst = true;
            foreach (KeyValuePair<string, string> pair in dParams)
            {
                if (bFirst) { sb.Append("?"); bFirst = false; }
                else sb.Append("&");
                sb.Append(pair.Key + "=" + pair.Value);
            }
            sRequestString = sb.ToString();
        }

        #endregion

        #region public methods
        public void LogIn()
        {
            LogIn(Username, sPassword);
        }

        public void LogIn(string username, string password)
        {
            sRequestType = "getLoginHash";
            dParams.Add("email", username);
            dParams.Add("password", password);

            executeRequest();

            XmlNode loginhash = xmlresponse.SelectSingleNode("descendant::response/login");
            if (loginhash != null)
            {
                bLoggedIn = true;
                sLoginHash = loginhash.Attributes["loginHash"].Value;
                iUserID = int.Parse(loginhash.Attributes["userId"].Value);
                userloggedIn();
            }
        }

        #region getAllTasks
        public void getAllTasks()
        {
        }

        public void getAllTasks(int amount)
        {
        }

        public List<voo2doTask> getAllTasksForProject(int projId)
        {
            if (LoggedIn)
            {
                sRequestType = "getAllTasks";
                dParams.Add("userId", iUserID.ToString());
                dParams.Add("loginHash", sLoginHash);
                dParams.Add("projId", projId.ToString());
                executeRequest();
                List<voo2doTask> retval = new List<voo2doTask>();
                XmlNodeList tasks = xmlresponse.SelectNodes("descendant::response/task");
                foreach (XmlNode xmltask in tasks)
                {
                    voo2doTask v2task = new voo2doTask();
                    v2task.TaskId = int.Parse(xmltask.Attributes["taskId"].Value);
                    v2task.TaskDescription = xmltask.Attributes["taskdesc"].Value;
                    //v2task.priority = xmltask.Attributes["priority"].Value;
                    string pri = "";
                    if (xmltask.Attributes["priority"].Value != "")
                        pri = xmltask.Attributes["priority"].Value.Substring(0, xmltask.Attributes["priority"].Value.IndexOf('.'));

                    if (pri != "")
                        v2task.priority = decimal.Parse(pri);
                    else
                        v2task.priority = 1;

                    if (xmltask.Attributes["projName"].Value != "")
                        v2task.projName = xmltask.Attributes["projName"].Value;

                    if (xmltask.Attributes["active"].Value != "")
                        v2task.active = int.Parse(xmltask.Attributes["active"].Value);

                    if (xmltask.Attributes["deadline"].Value != "")
                        v2task.deadline = DateTime.Parse(xmltask.Attributes["deadline"].Value);
                    else
                        v2task.deadline = DateTime.Now.AddYears(1);

                    if (xmltask.Attributes["dtcreated"].Value != "")
                        v2task.Created = DateTime.Parse(xmltask.Attributes["dtcreated"].Value);
                    else
                        v2task.Created = DateTime.Now.AddYears(1);

                    if (xmltask.Attributes["completed"].Value != "")
                        v2task.completed = DateTime.Parse(xmltask.Attributes["completed"].Value);
                    else
                        v2task.completed = DateTime.Now.AddYears(1);


                    retval.Add(v2task);
                }
                return retval;
            }
            else return null;
        }

        public void getAllTasksForProject(int projId, int amount)
        {
        }

        public void getAllTasksForView(int viewId)
        {
        }

        public void getAllTasksForView(int viewId, int amount)
        {
        }
        #endregion

        #region getIncompleteTasks
        public void getIncompleteTasks()
        {
        }

        public void getIncompleteTasks(int amount)
        {
        }

        public void getIncompleteTasksForProject(int projId)
        {
        }

        public void getIncompleteTasksForProject(int projId, int amount)
        {
        }

        public void getIncompleteTasksForView(int viewId)
        {
        }

        public void getIncompleteTasksForView(int viewId, int amount)
        {
        }
        #endregion

        #region getCompleteTasks
        public void getCompleteTasks()
        {
        }

        public void getCompleteTasks(int amount)
        {
        }

        public void getCompleteTasksForProject(int projId)
        {
        }

        public void getCompleteTasksForProject(int projId, int amount)
        {
        }

        public void getCompleteTasksForView(int viewId)
        {
        }

        public void getCompleteTasksForView(int viewId, int amount)
        {
        }
        #endregion

        #region getProjects
        public void getProjects()
        {
        }

        public void getProjectsForView(int viewId)
        {

        }
        #endregion

        #region getViews
        public List<voo2doView> getViews()
        {
            if (LoggedIn)
            {
                sRequestType = "getViews";
                dParams.Add("userId", iUserID.ToString());
                dParams.Add("loginHash", sLoginHash);
                executeRequest();
                List<voo2doView> retval = new List<voo2doView>();

                XmlNodeList views = xmlresponse.SelectNodes("descendant::response/view");
                foreach (XmlNode xmlview in views)
                {
                    voo2doView v2view = new voo2doView();
                    v2view.ViewId = int.Parse(xmlview.Attributes["viewId"].Value);
                    v2view.ViewName = xmlview.Attributes["viewName"].Value;
                    XmlNodeList proj = xmlview.ChildNodes;
                    foreach (XmlNode xmlproj in proj)
                    {
                        voo2doProject v2proj = new voo2doProject();
                        v2proj.ProjectId = int.Parse(xmlproj.Attributes["projId"].Value);
                        v2proj.ProjectName = xmlproj.Attributes["projName"].Value;
                        v2view.ProjectsInView.Add(v2proj);
                    }
                    retval.Add(v2view);
                }
                return retval;
            }
            else
                return null;
        }
        #endregion

        #region saveTask
        private void saveTask()
        {
        }

        #endregion


        #endregion
    }


    public class voo2doView
    {
        public string ViewName = "";
        public int ViewId = 0;
        public List<voo2doProject> ProjectsInView = new List<voo2doProject>();

    }

    public class voo2doProject
    {
        public string ProjectName = "";
        public int ProjectId = 0;
        public float estCurrent = 0;
        public float elapsed = 0;
        public List<voo2doTask> TasksInProject = new List<voo2doTask>();

        public int TaskCount
        {
            get { return TasksInProject.Count; }
        }
    }

    public class voo2doTask
    {
        public string TaskDescription = "";
        public decimal priority = 0;
        public string projName = "";

        public DateTime Created;
        public DateTime deadline;
        public DateTime completed;

        public float estOrig = 0;
        public float estCurr = 0;
        public float elapsed = 0;

        public int TaskId = 0;
        public int projId = 0;
        public int userId = 0;
        public int viewId = 0;
        public int collabId = 0;
        public int active = 1;

    }
}